package com.wbtech.ums;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.wbtech.ums.UmsAgent.SendPolicy;
import com.wbtech.ums.performance.GetCpu;
import com.wbtech.ums.performance.GetMemory;
import com.wbtech.ums.performance.GetPid;
import com.wbtech.ums.performance.GetTraffic;
import com.wbtech.ums.performance.MemoryDetailInfo;
import com.wbtech.ums.performance.TrafficDetailInfo;

import android.content.Context;
import android.util.Log;

public class DataManager {
	
	private Context context;
	private GetMemory getMemory;
	private GetPid getPid;
	private GetCpu getCpu;
	private GetTraffic getTraffic;
	private MemoryDetailInfo memInfo;
	private TrafficDetailInfo trafInfo;
	private String appKey;
	private String appVersion;
	private String deviceName;
	private String osVersion;
	private String totalMemory;
	private String coreNum;
	private String cpuName;
	private final String tag = "DataManager";
	private final String UPLOAD = "/performance/upload/";
	private final String fileName = "perform.txt";
	
//	private Timer timer;
	private ScheduledExecutorService scheduledThreadPool;

	public DataManager(Context context){
		this.context = context;
		init();
	}
	
	private void init(){
		getPid = new GetPid(context);
		int pids[] = new int[1];
		pids[0] = getPid.curPkgPid();
		getMemory = new GetMemory(context, pids);
		getCpu = new GetCpu(context, pids[0]);
		getTraffic = new GetTraffic(context);
		memInfo = new MemoryDetailInfo();
		trafInfo = new TrafficDetailInfo();
		AppInfo.init(context);
		DeviceInfo.init(context);
		initNoneChangeValue();
	}
	
	private void initNoneChangeValue(){
		appKey = AppInfo.getAppKey();
		appVersion = AppInfo.getAppVersion();
		deviceName = DeviceInfo.getDeviceName();
		osVersion = DeviceInfo.getOsVersion();
		getMemory.initMemDetailInfo(memInfo);
		totalMemory = memInfo.getTotalMemory();
		coreNum = getCpu.getCoreNum();
		cpuName = getCpu.getCpuName();
	}
	
	JSONObject performDataJSON() throws JSONException{
		JSONObject jsonObject = new JSONObject();
		
		jsonObject.put("appkey", appKey);
		jsonObject.put("version", appVersion);
		jsonObject.put("device", deviceName);
		jsonObject.put("os_version", osVersion);
		getMemory.initMemDetailInfo(memInfo);
		getTraffic.initTrafDetailInfo(trafInfo);
		jsonObject.put("memory", totalMemory);
		jsonObject.put("memory_rate", memInfo.getMemRate());
		
		//------------------------------------------------------------------------------
		//流量值_平均值
		jsonObject.put("flow", trafInfo.getTotalPerFlow());
		//-------------------------------------------------------------------------------
		
		jsonObject.put("cpu", "Name:" + coreNum + " CoreNum:" + cpuName);
		jsonObject.put("cpu_rate", getCpu.getCpuRatioInfo()[0]);
		jsonObject.put("date", String.valueOf(System.currentTimeMillis()));
		/*jsonObject.put("cpu", getCpu.getCpuRatioInfo()[0]);
		jsonObject.put("pss", memInfo.getTotalPss());
		jsonObject.put("3G", trafInfo.getMobilePerFlow());
		jsonObject.put("wifi", trafInfo.getWifiPerFlow());*/
		Log.v("DataManager", jsonObject.toString());
//		System.out.println(jsonObject.toString());
		return jsonObject;
	}

	/**
	 * Timer缺陷：
	 * 1. 单任务执行，若新添加线程切前一个线程执行时间大于两个线程执行的时间间隔，则第二个线程延期执行；
	 * 2. 不可以捕获异常，一旦抛出runtimeException，则不能后续继续执行新线程；
	 * 3. 任务周期依赖系统时间，系统时间变化会影响其执行；线程池基于时间的延迟，不受系统影响；
	 */
	public void updatePerfromDate(){
		int cpuCureNum = Integer.parseInt(coreNum);
		//IO较多，因此参考线程数为内核数2倍
		scheduledThreadPool = Executors.newScheduledThreadPool(cpuCureNum*2);
		scheduledThreadPool.scheduleAtFixedRate(new GetData(), 0, UmsConstants.mPerFormDataDelay, TimeUnit.MILLISECONDS);
//		timer = new Timer();
//		timer.scheduleAtFixedRate(new GetData(), 1000, UmsConstants.mPerFormDataDelay);
	}
	
	public void cancleUpdate(){
		scheduledThreadPool.shutdownNow();
//		timer.cancel();
	}
	/**
	 * 暂时不考虑网络不通的情况
	 * 因此wifi、3g为null的情况不存在
	 * 暂时不用CommonUtil.isNetworkAvailable();
	 */
	private class GetData implements Runnable {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			
			JSONObject jsonObject;
			try {
				jsonObject = performDataJSON();
				JSONArray jsonArray = new JSONArray();
				jsonArray.put(jsonObject);
				System.out.println("JSONArray is :"+ jsonArray);
				if (CommonUtil.getReportPolicyMode(context) == SendPolicy.REALTIME
						&& CommonUtil.isNetworkAvailable(context)) {
					String result = NetworkUtil.Post(UmsConstants.urlPrefix + UPLOAD, jsonArray.toString(), "json_str=");
					
					MyMessage message = NetworkUtil.parse(result);
					System.out.println("message is :"+message);
					if (message == null) {
						CommonUtil.saveInfoToFile("jsonObject", jsonObject,fileName, context);
						return;
					}
					if (message.getFlag() < 0) {
						CobubLog.e(tag, "Error Code=" + message.getFlag() + ",Message=" + message.getMsg());
						if (message.getFlag() == -4)
							CommonUtil.saveInfoToFile("jsonObject", jsonObject, fileName,context);
					}
				} else {
					CommonUtil.saveInfoToFile("jsonObject", jsonObject, fileName,context);
				}
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}
}
